package cn.szq.springframework.beans.factory.annotation;

import cn.hutool.core.bean.BeanUtil;
import cn.szq.springframework.beans.BeansException;
import cn.szq.springframework.beans.PropertyValues;
import cn.szq.springframework.beans.factory.BeanFactory;
import cn.szq.springframework.beans.factory.BeanFactoryAware;
import cn.szq.springframework.beans.factory.ConfigurableListableBeanFactory;
import cn.szq.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import cn.szq.springframework.utils.ClassUtils;

import java.lang.reflect.Field;

/**
 * @ClassName: AutowiredAnnotationBeanPostProcessor
 * @Description:
 * @Author: szq
 * @Date: 2021-09-22 14:01:02
 */
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        //1、处理注解，@value
        Class<?> clazz = bean.getClass();
        clazz = ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field field : declaredFields){
            Value annotation = field.getAnnotation(Value.class);
            if (null != annotation){
                String value = annotation.value();
                value = beanFactory.resolveEmbeddedValue(value);
                BeanUtil.setFieldValue(bean, field.getName(), value);
            }
        }

        //2、处理注解Autowired
        for(Field field : declaredFields){
            Autowired autowiredAnnotation = field.getAnnotation(Autowired.class);
            if (null != autowiredAnnotation){
                Class<?> type = field.getType();
                String dependentBeanName = null;
                Qualifier qualifierAnnotation = field.getAnnotation(Qualifier.class);
                Object dependentBean = null;
                if (null != qualifierAnnotation){
                    dependentBeanName = qualifierAnnotation.value();
                    dependentBean = beanFactory.getBean(dependentBeanName, type);
                }else{
                    dependentBean = beanFactory.getBean(type);
                }
                BeanUtil.setFieldValue(bean, field.getName(), dependentBean);
            }
        }

        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
}
